//FPV-BASE 1.0
	
	
/*
	
	$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A

			RMC          Recommended Minimum sentence C
			123519       Fix taken at 12:35:19 UTC
			A            Status A=active or V=Void.
			4807.038,N   Latitude 48 deg 07.038' N
			01131.000,E  Longitude 11 deg 31.000' E
			022.4        Speed over the ground in knots
			084.4        Track angle in degrees True
			230394       Date - 23rd of March 1994
			003.1,W      Magnetic Variation
			*6A          The checksum data, always begins with *
		
*/
	
	
	
	#include "TinyGPSMod.h"
	#include <NewSoftSerial.h>
	#include <LiquidCrystal.h>
	#include <Tone.h>

	
	// Constantes
	#include "WProgram.h"
void setup();
void loop();
bool feedgps();
void pitar(int frecuencia, int duracion, int veces, int espacio);
float leevoltimetro (int entrada, int valmax);
const int BUZZER = 14;			// Pin donde esta el buzzer
	const int BATERIA = 5;			// Pin donde esta el voltimero de la bateria
	
	const float BATALERTA = 11.00;   // Para alarma de bateria baja
	const float BATALARMA = 10.50;	// Para alarma de bateria muy baja
	
	// Objetos de librerias
	LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
	TinyGPSMod migps;
	NewSoftSerial nss(2, 3);
	Tone zumbador;					// Pitidos de 1000Hz son suaves. De 1800 Hz los que mas suenan.
	

	// Definicion de funciones que si no no se ven bien (no se muy bien por que)
	void printdato(TinyGPSMod &gpsobj);
	
	
	// Variables cambiantes de programa
	float tension = 0;
	int cicloprograma = 0;
	boolean recibiendo = false;
	long lat, lon;
	unsigned long fix;
		
	
	void setup(){												// RUTINA DE CONFIGURACION
	
		pinMode(BUZZER, OUTPUT);
			
		lcd.begin(2, 16);
		Serial.begin(57600);										// Iniciar puero de comunicaciones
		nss.begin(57600);
		zumbador.begin(BUZZER);
		
		lat = 0;
		lon = 0;
		
		Serial.println("ESTACION FPV 1.0 OK");
		
		lcd.print("FPV BASE  1.0 OK");
			
		delay(2000);
		
		lcd.clear();
		
		pitar(1000, 100, 2, 100); 		// int frecuencia, int duracion, int veces, int espacio
					
		
	}
	
	
	
	void loop(){												// BUCLE DE PROGRAMA
	
	
		bool newdata = false;
		unsigned long start = millis();

		while (millis() - start < 4000){						// Este ciclo es rapido y se sale cada XXXX ms
																// Se pueden meter aqui comprobaciones importantes para hacerlo salir antes
			if (feedgps())
			newdata = true;
			
		}
		
	
		switch (cicloprograma) {								// Cada ciclo hacemos una cosa
		
		
			case 0:												// Ciclo 0, comprobar baterias
	
				tension = leevoltimetro(BATERIA, 14);
				if (feedgps()) newdata = true;
				lcd.clear();
		
				if (tension < BATALERTA) {
		
					lcd.print("  BATERIA BAJA  ");
					pitar(1800, 200, 2, 500);					// Estos pitidos hay que cambiarlos para lanzarlos aqui y pararlos en el ciclo rapidisimo ...
		
				}
		
				else if (tension < BATALARMA) {
		
					lcd.print("BATERIA MUY BAJA");
					pitar(1800, 1000, 2, 1000);
		
				}
		
				else {
		
					lcd.print(" BATERIA NORMAL ");
		
				}
		
				if (feedgps()) newdata = true;
				lcd.setCursor(0, 1);
				lcd.print("TENSION: ");
				if (tension < 10.00) lcd.print("0");
				lcd.print(tension);
				lcd.print(" V");
				break;
		
		
			case 1:												// ciclo 1, coordenadas
			
				if (feedgps()) newdata = true;
				lcd.clear();
				
		
				if (newdata){
    
					//printdato(migps);
					if ( recibiendo == false ) {
						//noInterrupts();
						pitar(1000, 1000, 1, 0);
						recibiendo = true;
						//delay(1000);
						//interrupts();
					}
					lcd.print(" RECIBIENDO GPS ");
					
				}
		
				else {
		
					if ( recibiendo == true ) {
						pitar(1800, 400, 3, 200);
						recibiendo = false;
					}
					lcd.print ("SIN POSICION GPS");
					Serial.println("SIN POSICION GPS");
		
				}
				
				feedgps();
				break;
		
		
			case 2:
			
				lcd.clear();
				
				if (newdata) migps.get_position(&lat, &lon, &fix);
				
				lcd.print("LAT: ");
				lcd.print(lat);
				lcd.setCursor(0, 1);
				lcd.print("LON: ");
				lcd.print(lon);
				
				feedgps();
				if (!newdata) cicloprograma++;	// Si no hay dato saltarse el paso 3
				break;
			
			
			case 3:
			
				lcd.clear();
				lcd.print("RUM: ");
				lcd.print(migps.course());
				lcd.print("ALT: ");
				lcd.print(migps.altitude() / 100);
				lcd.setCursor(0, 1);
				lcd.print("VEL: ");
				lcd.print(migps.speed());
				
				feedgps();
				break;
				
		}
		
		if (cicloprograma == 3) { cicloprograma = 0;}		// Para incremenbtar el contador de ciclo
		else {cicloprograma++;}
	

	}

	
	bool feedgps(){
  
  
			while (nss.available()){
  
				char c = nss.read();
				Serial.print(c);
				if (migps.encode(c)) {return true;}
	  
			}
  
			return false;
		
	}
	
/*
	void printdato (TinyGPSMod &gpsobj) {
	
		long lat, lon;
		unsigned long fix, fecha, hora, chars;
		//int ano;
		//byte month, day, hour, minute, second, hundredths;
		unsigned short sentences, fallidas;
	
		Serial.println(" ");
		Serial.println("ESTADO DEL GPS ...");
		Serial.println("------------------");
		
		gpsobj.get_position(&lat, &lon, &fix);
	
		Serial.print("Lat/Long: "); Serial.print(lat); Serial.print(", "); Serial.println(lon); 
		Serial.print("Fix     : "); Serial.print(fix); Serial.println("ms.");
	
		feedgps();
		
		Serial.print("Alt(cm): "); Serial.println(gpsobj.altitude()); 
		Serial.print("Rumbo  : "); Serial.println(gpsobj.course()); 
		Serial.print("VNudos : "); Serial.println(gpsobj.speed());
		
		feedgps();

		gpsobj.stats(&chars, &sentences, &fallidas);
		Serial.print("Chars  : "); Serial.println(chars); 
		Serial.print("Sent.  : "); Serial.println(sentences); 
		Serial.print("Fallos : "); Serial.println(fallidas);
		Serial.println("------------------");
		Serial.println(" ");
	}

*/
	
	void pitar(int frecuencia, int duracion, int veces, int espacio) {
	
		while (veces > 0) {
	
			zumbador.play(frecuencia, duracion);
			delay(espacio + duracion);
		
		veces--;
	
		}
		
	}
	
	
	float leevoltimetro (int entrada, int valmax) {	// lee una entrada analogica y devuelve el valor real (en funcion al valmax que es el valor que corresponde a 5V)
	
		int lectura;
	
		float factor = float(valmax) / 1023.00;	// Calculo del factor. Fijarse en la conversion de valmax a float y los fijos que llevan coma
		lectura = analogRead(entrada);
		return float(lectura) * factor;
		
	}
	

int main(void)
{
	init();

	setup();
    
	for (;;)
		loop();
        
	return 0;
}

